﻿using GJKAlgorithm;
using LineTools;
using Sample03;
using Sample05;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using static GJKAlgorithm.GJK2DEngine;

/// <summary>
/// GJK算法主入口
/// </summary>
public class GJK2DMain : MonoBehaviour
{
    [Header("是否绘制最近距离")]
    public bool IsDrawContractLine = false;

    private Rect OrignalRect;

    [SerializeField]
    private List<Shape2D> shapeList = new List<Shape2D>();

    private GUIStyle orignalTxtStyle;

    private GJK gjk;

    public void Awake()
    {
        gjk = new GJK();
        orignalTxtStyle = new GUIStyle();
        orignalTxtStyle.normal.textColor = Color.red;
        orignalTxtStyle.fontSize = 32;
    }


    public void Start()
    {
        Vector3 originalPos = Camera.main.WorldToScreenPoint(Vector3.zero);
        Debug.Log("width :" + Screen.width / 2 + " height :" + Screen.height / 2);
        Debug.Log(originalPos);
        OrignalRect = new Rect(originalPos.x + 5, Screen.height - originalPos.y + 5, 50, 50);
    }

    public void Update()
    {
        LineTool.Instance().BeginDraw();
        DrawAxis();
        DrawShape();
        DrawMinkowski();
        UpdateSelection();
        CheckContractState();
        LineTool.Instance().EndDraw();
        //if (Input.GetKeyDown(KeyCode.P)) {
        //    CheckContractState();
        //}

    }

    private void DrawMinkowski()
    {
        var points = MinkowskiTool.computeMinkowskiSet(shapeList[0], shapeList[1]);
        LineTool.Instance().DrawPolygon(points, Color.grey);
        //DrawPolygon(points, Color.grey);
    }

    private void CheckContractState()
    {
        for (int i = 0; i < 1; i++)
        {
            bool isContract = false;
            for (int j = 0; j < shapeList.Count; j++)
            {
                if (i == j) continue;
                /*
               if (gjk.queryCollision(new Shape(shapeList[i].vertices), new Shape(shapeList[j].vertices))) {
                   isContract = true;
               }
                */
                Vector2 AClosesetP;
                Vector2 BClosesetP;
                List<SupportPoint> simplex;
                Vector2 EPADir;
                if (GJK2DEngine.IsContract(shapeList[i].vertices, shapeList[j].vertices, out AClosesetP, out BClosesetP, out simplex, out EPADir,IsDrawContractLine))
                {
                    LineTool.Instance().DrawLine(EPADir, Vector2.zero, Color.yellow);
                    isContract = true;
                }
                else
                {
                    //Debug.Log("AClosesetP :" + AClosesetP + "BClosesetP :"+ BClosesetP);
                    LineTool.Instance().DrawLine(simplex[0].GetPoint(), simplex[1].GetPoint(), Color.blue);
                    LineTool.Instance().DrawLine(AClosesetP, BClosesetP, Color.red);
                    
                }

            }
            if (isContract)
            {
                shapeList[i].LineColor = Color.red;
            }
            else
            {
                shapeList[i].LineColor = Color.green;
            }
        }
    }

    private void DrawShape()
    {
        for (int i = 0; i < shapeList.Count; i++)
        {
            shapeList[i].DrawPolygon();
        }
    }

    public void OnGUI()
    {
        GUI.Label(OrignalRect, "(0,0)", orignalTxtStyle);
    }


    void DrawAxis()
    {
        Color color = Color.white;
        float lineWidth = 0.02f;

        var renderer = LineTool.Instance().DrawLine(new Vector2(0, -10), new Vector2(0, 10), color);
        renderer.startWidth = lineWidth;
        renderer.endWidth = lineWidth;

        renderer = LineTool.Instance().DrawLine(new Vector2(-10, 0), new Vector2(10, 0), color);
        renderer.startWidth = lineWidth;
        renderer.endWidth = lineWidth;
    }

    int selectedIndex = -1;
    Vector2 selectedOffset;
    float selectedAngle;

    void UpdateSelection()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Vector2 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition + new Vector3(0, 0, 10));

            selectedIndex = -1;
            for (int i = 0; i < shapeList.Count; ++i)
            {
                if (UtilityTool.contains(shapeList[i].vertices, mousePos))
                {
                    selectedIndex = i;
                    break;
                }
            }

            if (selectedIndex >= 0)
            {
                var t = shapeList[selectedIndex].transform;
                Vector2 position = t.position;
                selectedOffset = mousePos - position;

                float mouseAngle = Mathf.Atan2(selectedOffset.y, selectedOffset.x) * Mathf.Rad2Deg;
                selectedAngle = mouseAngle - t.eulerAngles.z;
            }
        }
        else if (Input.GetMouseButtonUp(0))
        {
            selectedIndex = -1;
        }
        else if (Input.GetMouseButton(0))
        {
            if (selectedIndex < 0)
            {
                return;
            }

            Transform t = shapeList[selectedIndex].transform;

            Vector2 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition + new Vector3(0, 0, 10));
            if (selectedOffset.magnitude < 0.4f) // 移动
            {
                Vector3 position = t.position;
                position.x = mousePos.x - selectedOffset.x;
                position.y = mousePos.y - selectedOffset.y;
                t.position = position;
            }
            else // 旋转
            {
                Vector2 position = t.position;
                Vector2 mouseDir = mousePos - position;
                float mouseAngle = Mathf.Atan2(mouseDir.y, mouseDir.x) * Mathf.Rad2Deg;

                float angle = mouseAngle - selectedAngle;
                t.eulerAngles = new Vector3(0, 0, angle);
            }
        }
    }
}
